package com.utils;

import cn.hutool.db.DbRuntimeException;
import cn.hutool.db.DbUtil;
import cn.hutool.db.meta.Column;
import cn.hutool.db.meta.TableType;
import com.entity.generate.FkBean;
import com.entity.generate.Table;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @ClassName MetaUtil
 * @Description TODO
 * @Author 谭庆伟
 * @Date 2020/8/21 16:13
 * @Version 1.0
 **/
@Component
public class MetaUtil {
    @Autowired
    private DataSource dataSource;
    public MetaUtil() {
    }


    /**
     * 获取catalog，获取失败返回{@code null}
     *
     * @param conn {@link Connection} 数据库连接，{@code null}时返回null
     * @return catalog，获取失败返回{@code null}
     * @since 4.6.0
     */
    private String getCataLog(Connection conn) {
        if (null == conn) {
            return null;
        }
        try {
            return conn.getCatalog();
        } catch (SQLException e) {
            // ignore
        }

        return null;
    }

    /**
     * 获得表的元信息
     *
     * @param tableName 表名
     * @return Table对象
     */
    public Table getTableMeta(String dbName, String tableName) {
        final Table table = Table.create(tableName);
        try (Connection conn = dataSource.getConnection()) {
            // catalog和schema获取失败默认使用null代替
            String schema = getSchema(conn);
            DatabaseMetaData metaData = conn.getMetaData();
            // 获得表元数据（表注释）
            try (ResultSet rs = metaData.getTables(dbName, schema, tableName, new String[]{TableType.TABLE.value()})) {
                if (null != rs) {
                    if (rs.next()) {
                        table.setComment(rs.getString("REMARKS"));
                    }
                }
            }
            // 获得主键
            try (ResultSet rs = metaData.getPrimaryKeys(dbName, schema, tableName)) {
                if (null != rs) {
                    while (rs.next()) {
                        table.addPk(rs.getString("COLUMN_NAME"));
                    }
                }
            }
            /*
             *  <LI><B>FKTABLE_NAME</B> String {@code =>} foreign key table name
             *  <LI><B>FKCOLUMN_NAME</B> String {@code =>} foreign key column name
             *  <LI><B>KEY_SEQ</B> short {@code =>} sequence number within a foreign key( a value
             *  of 1 represents the first column of the foreign key, a value of 2 would
             */
            try (ResultSet rs = metaData.getImportedKeys(dbName, schema, tableName)) {
                if (null != rs) {
                    System.out.println(rs);
                    while (rs.next()) {

                        FkBean fkBean = new FkBean();
                        fkBean.setFkColumnName(rs.getString("FKCOLUMN_NAME"));
                        fkBean.setReferencesTableName(rs.getString("PKTABLE_NAME"));
                        fkBean.setReferencesColumnName(rs.getString("PKCOLUMN_NAME"));
                        table.addFk(fkBean);
                    }
                }
            }
            // 获得列
            try (ResultSet rs = metaData.getColumns(dbName, schema, tableName, null)) {
                if (null != rs) {
                    while (rs.next()) {
                        table.setColumn(Column.create(tableName, rs));
                    }
                }
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return table;
    }

    /**
     * 获取schema，获取失败返回{@code null}
     *
     * @param conn {@link Connection} 数据库连接，{@code null}时返回null
     * @return schema，获取失败返回{@code null}
     * @since 4.6.0
     */
    public String getSchema(Connection conn) {
        if (null == conn) {
            return null;
        }
        try {
            return conn.getSchema();
        } catch (SQLException e) {
            // ignore
            e.printStackTrace();
        }

        return null;
    }

}
